﻿using System;
using System.Data;
using System.Text;
using System.Web;
using Me.Amon.C;
using Me.Amon.Da.Db;
using Me.Amon.Da.Db.OMS;
using Me.Amon.POS.C;
using Me.Amon.POS.M;
using Me.Amon.Util;
using Newtonsoft.Json;
using Me.Amon.M;

namespace Me.Amon.POS
{
    /// <summary>
    /// Spu 的摘要说明
    /// </summary>
    public class Spu : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            context.Response.ContentEncoding = Encoding.UTF8;

            var obj = new MSpu();

            // 公司
            var corp = context.Request[PPos.PARAM_KEY_CORP];
            if (string.IsNullOrEmpty(corp))
            {
                obj.error_code = PPos.ERROR_CODE_CORP_EMPTY;
                context.Response.Write(JsonConvert.SerializeObject(obj, Formatting.None));
                context.Response.End();
                return;
            }

            // 操作
            var opt = context.Request[PPos.PARAM_KEY_OPT];
            if (string.IsNullOrEmpty(opt))
            {
                obj.error_code = PObj.ERROR_CODE_OPT_EMPTY;
                context.Response.Write(JsonConvert.SerializeObject(obj, Formatting.None));
                context.Response.End();
                return;
            }

            // 数据
            var dat = context.Request[PPos.PARAM_KEY_DATA];
            if (string.IsNullOrWhiteSpace(dat))
            {
                obj.error_code = PPos.ERROR_CODE_DAT_EMPTY;
                context.Response.Write(JsonConvert.SerializeObject(obj, Formatting.None));
                context.Response.End();
                return;
            }

            switch (opt)
            {
                case PPos.PARAM_VALUE_OPT_SELECT:
                    SelectSpu(corp, dat, context);
                    break;
                case PPos.PARAM_VALUE_OPT_CREATE:
                    CreatSpu(corp,context);
                    break;
                case PPos.PARAM_VALUE_OPT_UPDATE:
                    break;
                case PPos.PARAM_VALUE_OPT_DELETE:
                    break;
                default:
                    obj.error_code = PObj.ERROR_CODE_OPT_ERROR;
                    context.Response.Write(JsonConvert.SerializeObject(obj, Formatting.None));
                    break;
            }
            context.Response.End();
        }

        private void CreatSpu(string corp, HttpContext context)
        {
            var data = context.Request[PPos.PARAM_KEY_DATA];

            MSpu spu = null;
            try
            {
                spu = JsonConvert.DeserializeObject<MSpu>(data);
            }
            catch (Exception exp)
            {
                var obj = new MObj();
                obj.error_code = PObj.ERROR_CODE_CUSTOM;
                obj.error_message = exp.Message;
                context.Response.Write(JsonConvert.SerializeObject(obj, Formatting.None));
                context.Response.End();
                return;
            }

            var dba = new RDBEngine();
            string code = "";
            code = KeyUtil.NextSpuKey(dba, spu.corp_id);

            //dba.AddTable(DSpu.TABLE);
            dba.AddParam(DSpu.CORP_ID, spu.corp_id);
            dba.AddParam(DSpu.NAME, spu.name);
            dba.AddParam(DSpu.UOM_ID, spu.uom_id);
            dba.AddParam(DSpu.MERCHANT_ID, "");
            dba.AddParam(DSpu.MERCHANT_CODE, "");
            dba.AddParam(DSpu.MERCHANT_NAME, "");
            dba.AddParam(DSpu.USABLE_INV, spu.usable_inv);
            dba.AddParam(DSpu.MAX_INV, 0);
            dba.AddParam(DSpu.MIN_INV, 0);
            dba.AddParam(DSpu.UPDATE_TIME, DSpu.NOW, false);
            //dba.AddParam(DSpu.UPDATE_USER, user.UserId);

            var id = HashUtil.UtcTimeInHex();
            dba.AddParam(DSpu.ID, id);
            dba.AddParam(DSpu.CODE, code);
            dba.AddParam(DSpu.CREATE_TIME, DSpu.NOW, false);
            //dba.AddParam(DSpu.CREATE_USER, user.UserId);

            dba.ExecuteInsert();

            context.Response.Write(JsonConvert.SerializeObject(spu));
        }

        private void SelectSpu(string corp, string key, HttpContext context)
        {
            var sPage = context.Request[PPos.PARAM_KEY_PAGE] ?? "";
            var iPage = 0;
            if (CharUtil.IsValidateLong(sPage))
            {
                iPage = int.Parse(sPage);
            }
            var sSize = context.Request[PPos.PARAM_KEY_PAGE_SIZE] ?? "";
            var iSize = 5;
            if (CharUtil.IsValidateLong(sSize))
            {
                iSize = int.Parse(sSize);
            }

            key += '%';
            var sql = new StringBuilder();
            sql.Append(" SELECT *");
            sql.Append(" FROM ").Append(DSpu.TABLE);
            sql.Append(" WHERE ").Append(DSpu.CORP_ID).Append(" = '").Append(corp).Append("'");
            sql.Append("     AND ").Append(DSpu.ID).Append(" IN(SELECT");
            sql.Append("               ").Append(DSpuBarcode.SPU_ID);
            sql.Append("             FROM ").Append(DSpuBarcode.TABLE);
            sql.Append("             WHERE ").Append(DSpuBarcode.BARCODE).Append(" LIKE '").Append(key).Append("')");
            sql.Append("      OR ").Append(DSpu.CODE).Append(" LIKE '").Append(key).Append("'");
            sql.Append("      OR ").Append(DSpu.HYPY).Append(" LIKE '").Append(key).Append("'");

            var dba = new RDBEngine();
            var dt = dba.ExecuteSelect(sql.ToString());
            var s = iPage * iSize;
            var t = s + iSize;
            var c = dt.Rows.Count;
            if (t > c)
            {
                t = c;
            }
            var spus = new MSpu[t - s];
            c = 0;
            while (s < t)
            {
                spus[c++] = ReadSpu(dt.Rows[s++], dba);
            }

            context.Response.Write(JsonConvert.SerializeObject(spus));
        }

        private MSpu ReadSpu(DataRow row, RDBEngine dba)
        {
            var spu = new MSpu();
            spu.id = row[DSpu.ID] as string;
            spu.code = row[DSpu.CODE] as string;
            spu.name = row[DSpu.NAME] as string;
            spu.hypy = row[DSpu.HYPY] as string;
            spu.mode = row[DSpu.MODE] as string;
            spu.spec = row[DSpu.SPEC] as string;
            spu.is_vip = 1 == (int)row[DSpu.IS_VIP];
            spu.is_pro = 1 == (int)row[DSpu.IS_PRO];
            spu.has_point = 1 == (int)row[DSpu.HAS_POINT];

            ReadInv(spu, dba);
            ListBar(spu, dba);
            ReadPrice(spu, dba);
            return spu;
        }

        private void ReadInv(MSpu spu, RDBEngine dba)
        {

            dba.Reset();
            dba.AddTable(DSpuInv.TABLE);
            dba.AddColumn(DSpuInv.INV);
            dba.AddColumn(DSpuInv.SOURCE);
            dba.AddColumn(DSpuInv.ORDER_ID);
            dba.AddColumn(DSpuInv.ORDER_CODE);
            dba.AddWhere(DSpuInv.SPU_ID, spu.id);
            dba.AddSort(DSpuInv.CREATE_TIME, true);
            var dt = dba.ExecuteSelect();
            if (dt.Rows.Count < 1)
            {
                return;
            }

            MSpuInv inv = new MSpuInv();
            DataRow row = dt.Rows[0];

            inv.inv = (int)row[DSpuInv.INV];
            inv.source = (int)row[DSpuInv.SOURCE];
            inv.order_id = row[DSpuInv.ORDER_ID] as string;
            inv.order_code = row[DSpuInv.ORDER_CODE] as string;

            spu.inv = inv;
        }

        private void ListBar(MSpu spu, RDBEngine dba)
        {
            dba.Reset();
            dba.AddTable(DSpuBarcode.TABLE);
            dba.AddColumn(DSpuBarcode.BARCODE);
            dba.AddWhere(DSpuBarcode.SPU_ID, spu.id);
            dba.AddWhere(DSpuBarcode.STATUS, CSpuBarcode.STATUE_ENABLED.ToString(), false);
            var dt = dba.ExecuteSelect();
            var cnt = dt.Rows.Count;
            spu.barcodes = new MSpuBarcode[cnt];
            MSpuBarcode bar;
            DataRow row;
            for (int i = 0; i < cnt; i += 1)
            {
                row = dt.Rows[i];

                bar = new MSpuBarcode();
                bar.code = row[DSpuBarcode.BARCODE] as string;
                spu.barcodes[i] = bar;
            }
        }

        private void ReadPrice(MSpu spu, RDBEngine dba)
        {
            var now = DateTime.Now.ToString("yyyy-MM-dd");

            dba.Reset();
            dba.AddTable(DSpuPrice.TABLE);
            dba.AddColumn(DSpuPrice.PRICE);
            dba.AddColumn(DSpuPrice.VIP_TYPE);
            dba.AddColumn(DSpuPrice.VIP_PRICE);
            dba.AddColumn(DSpuPrice.PRO_TYPE);
            dba.AddColumn(DSpuPrice.PRO_PRICE);
            dba.AddColumn(DSpuPrice.PRO_NAME);
            dba.AddColumn(DSpuPrice.VALID_DATES);
            dba.AddColumn(DSpuPrice.VALID_DATET);
            dba.AddWhere(DSpuPrice.SPU_ID, spu.id);
            dba.AddWhere(string.Format("DATE({0})", DSpuPrice.VALID_DATES), "<=", now, true);
            dba.AddWhere(string.Format("{0} = '' OR DATE({0}) >= '{1}'", DSpuPrice.VALID_DATET, now));
            dba.AddWhere(DSpuPrice.STATUS, CSpuPrice.STATUE_ENABLED.ToString(), false);
            dba.AddSort(DSpuPrice.CREATE_TIME, true);
            var dt = dba.ExecuteSelect();
            if (dt.Rows.Count < 1)
            {
                return;
            }

            MSpuPrice price = new MSpuPrice();
            DataRow row = dt.Rows[0];
            price.price = (int)row[DSpuPrice.PRICE];
            price.vip_type = (int)row[DSpuPrice.VIP_TYPE];
            price.vip_price = (int)row[DSpuPrice.VIP_PRICE];
            price.pro_type = (int)row[DSpuPrice.PRO_TYPE];
            price.pro_price = (int)row[DSpuPrice.PRO_PRICE];
            price.pro_name = row[DSpuPrice.PRO_NAME] as string;
            price.valid_dates = row[DSpuPrice.VALID_DATES] as string;
            price.valid_datet = row[DSpuPrice.VALID_DATET] as string;
            spu.price = price;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        public System.Web.SessionState.HttpSessionState Session { get; set; }
    }
}